//
//  FixedWidthInteger.swift
//  MJRefresh
//
//  Created by tucici on 2024/6/14.
//

import UIKit

//MARK: - //遵从该协议的基本数据类型，String，Bool，可转换成int8, int16, int32, int64
/// 遵从该协议的基本数据类型，String，Bool，可转换成int8, int16, int32, int64
public protocol TCC_Int_hex_protocol: CVarArg{
    var int8 : Int8{ get}
    var int16 : Int16{ get}
    var int32 : Int32{ get}
    var int64 : Int64{ get}
}

public extension TCC_Int_hex_protocol {
    var int8 : Int8{ return Int8(self.int)}
    var int16 : Int16{ return Int16(self.int)}
    var int32 : Int32{ return Int32(self.int)}
    var int64 : Int64{ return Int64(self.int)}
    
    private var int : Int{
        do{
            switch self {
            case is Int,
                is Float,
                is CGFloat,
                is Double,
                is Int8,
                is Int16,
                is Int32,
                is Int64:
                let value = String(format: "%f", self)
                let doubleValue = Double(value) ?? 0
                return Int(doubleValue)
            case is String:
                let value = self as? String ?? "0"
                let trimmedValue = value.trimmingCharacters(in: .whitespaces)
                
                guard let n = Int(trimmedValue) else{
                    guard let n2 = Int(trimmedValue, radix: 16) else{
                        throw NSError(domain: "字符串转整数型错误： \(trimmedValue)类型错误", code: 1001, userInfo: nil)
                    }
                    return n2
                }
                return n
            case is Bool:
                let value = self as? Bool ?? false
                return value ? 1 : 0
            default:
                throw NSError(domain: "字符串转整数型错误： \(self)转换错误", code: 1001, userInfo: nil)
            }
        }
        catch{
            return 0;
        }
    }
}


//MARK: - //小数点后保留指定的位数的协议
public typealias tcc_float_float_block = (Int)->CGFloat
public typealias tcc_float_string_block = (Int)->String
/// 小数点后保留指定的位数的协议
public protocol TCC_Float_protocol{
    /// 小数点后保留指定的位数->CGFloat格式
    var rounded : tcc_float_float_block?{get}
    /// 小数点后保留指定的位数->String格式
    var string : tcc_float_string_block?{get}
}
public extension TCC_Float_protocol{
    var rounded : tcc_float_float_block?{
        return { n in
            if (self is CGFloat) == false &&
                (self is Float) == false &&
                (self is Double) == false &&
                (self is Int){
                return 0.0
            }
            let str = "\(self)"
            let value = CGFloat((str as NSString).doubleValue)
            let divisor = pow(10.0, CGFloat(n))
            return (value * divisor).rounded() / divisor
        }
    }
    
    var string : tcc_float_string_block?{
        return { n in
            if (self is CGFloat) == false &&
                (self is Float) == false &&
                (self is Double) == false &&
                (self is Int){
                return ""
            }
            let str = "\(self)"
            let value = CGFloat((str as NSString).doubleValue)
            return String(format: "%.\(n)f", value)
        }
    }
}



//MARK: - // [Uint8] 的一些快捷方法
public extension Array where Element == UInt8{
    ///[UInt8]打印
    var description: String {
        return self.map { String(format: "%02X", $0) }.joined(separator: ", ")
    }
    ///[UInt8]转换成Int
    var int : Int{
        var decimalValue: UInt64 = 0
        // 遍历数组并计算十进制值
        for byte in self {
            decimalValue = (decimalValue << 8) | UInt64(byte)
        }
        return Int(decimalValue)
    }
}

//MARK: - // FixedWidthInteger协议 的一些快捷方法
public extension FixedWidthInteger {
    ///int 按位 转换成16进制字符串
    /// let num :  Int8 =  15   =>  num.hex = "0F"， 8bit 的int 转换成 1个字节的16进制字符串
    /// let num :  Int16 =  15   =>  num.hex = "000F"，16bit的int类型 转换成 2个字节的16进制字符串
    /// let num :  Int32 =  15   =>  num.hex = "0000000F" 32bit的int类型 转换成 4个字节的16进制字符串
    var hexBit: String {
        return String(format: "%0\(self.bitWidth / 4)X", self as! CVarArg)
    }
    
    /// int 按位 转换成[Uint8]数组
    /// let num :  Int8 =  15   =>  num.bytes = [0x0F]， 8bit 的int 转换成 长度1的uint8 数组
    /// let num :  Int16 =  15   =>  num.bytes = [0x00, 0x0F]， 16bit 的int 转换成 长度2的uint8 数组
    /// let num :  Int32 =  15   =>  num.bytes = [0x00, 0x00, 0x00, 0x0F]， 32bit 的int 转换成 长度4的uint8 数组
    var bytesBit : [UInt8]{
        let length = self.bitWidth / 8
        var array = [UInt8](repeating: 0, count: length)
        for i in 0..<length {
            let bin = (length - 1 - i) * 8
            array[i] = UInt8((Int(self) >> bin) & 0xFF)
        }
        return array
    }
    
    var hex : String{
        return String(format: "%02X", self as! CVarArg)
    }
    
    ///10进制转换成 [Uint8]数组
    var bytes: [UInt8] {
        var value = self
        var byteArray: [UInt8] = []
        
        // 循环获取每一个字节，并加入数组中
        for _ in 0..<MemoryLayout<Self>.size {
            byteArray.insert(UInt8(value & 0xFF), at: 0)
            value >>= 8
            
            // 如果剩下的值为0，就可以停止
            if value == 0 {
                break
            }
        }
        return byteArray
    }
    
    
    var int8 : Int8{ return Int8(self)}
    var int16 : Int16{ return Int16(self)}
    var int32 : Int32{ return Int32(self)}
    var int64 : Int64{ return Int64(self)}
    var uint8 : UInt8{
        if self >= 0 {
            return UInt8(self)
        }else{
            print("负值不能转换为 UInt8")
            return UInt8(self)
        }
    }
}
extension CGFloat : TCC_Int_hex_protocol,TCC_Float_protocol{
}
extension Double : TCC_Int_hex_protocol,TCC_Float_protocol{
}
extension Float : TCC_Int_hex_protocol,TCC_Float_protocol{
}
extension Bool : TCC_Int_hex_protocol{
}
extension String : TCC_Int_hex_protocol{
}

